\section{Previous work}

\subsection{Process-based debugging}

With systems like \unix{}, debugging is usually performed as an
interaction between two \emph{processes}.  The debugger runs in one
process and the application in another process.  For a breakpoint, the
code of the application is modified by the debugger so that the
application sends a signal to the debugger when the breakpoint has
been reached.  For this purpose, the debugger maps the code pages of
the application as \emph{copy on write} (or COW).  With this
technique, instances of the same application that are not executed
under the control of the debugger are not affected by the modified
code.  In particular, with this technique, any application can be
debugged, including the debuggger itself.

Some FLOSS \commonlisp{} implementations suggest the use of
this debugging technique, by means of some existing debugger such as GDB%
\footnote{https://sourceware.org/gdb/current/onlinedocs/gdb/}
(also \cite{Stallman:gdb}), in order
to set breakpoints.  In particular, the \ccl{}
\seesec{sec-previous-ccl} documentation mentions that this technique
is possible, and it is also the technique recommended for \ecl{}
\seesec{sec-previous-ecl}.

\subsection{\sbcl{}}

The \sbcl{} \commonlisp{} implementation%
\footnote{http://www.sbcl.org/}
has a breakpoint facility.  Given a code location, a breakpoint can be
set, which results in the code being modified at that location, so
that an arbitrary function (given to the constructor of the
breakpoint) is called when execution reaches that location.

The only feature that uses the breakpoint facility is \texttt{trace}.
Furthermore, it is hard for the user to take advantage of the
breakpoint facility directly, given that a function such as
\texttt{make-breakpoint} requires an argument indicating the code
location.  We are unaware of the existence of a debugger for \sbcl{}
that can use the breakpoint facility.

\sbcl{} also has a \emph{single stepper} that the manual says is
``instrumentation based''.  As it turns out, the kind of
instrumentation used by the stepper is not that of the breakpoint
facility.  Instead, when the value of the \texttt{debug} optimization
quality is sufficiently high compared to the values of other
optimization qualities, the compiler inserts code that signals
conditions that are specific to the stepper.

\subsection{\ccl{}}
\label{sec-previous-ccl}

The \ccl{} \commonlisp{} implementation%
\footnote{https://ccl.clozure.com/}
does not have the concept of breakpoints.

The \ccl{} \texttt{trace} command uses \emph{encapsulation}, meaning
that the association between the \emph{name} of a function and the
function object itself is altered so that it contains a \emph{wrapper}
function that displays the information requested and that calls the
original function to accomplish its task.

Currently, \ccl{} does not have a working single stepper.

\subsection{\ecl{}}
\label{sec-previous-ecl}

The \ecl{} \commonlisp{} implementation%
\footnote{https://common-lisp.net/project/ecl/}
does not have the concept of breakpoints, so an external debugger such
as GDB has to be used for breakpoints.  \ecl{} does have a special
instruction type in the bytecode virtual machine that is used for
stepping.

The \texttt{trace} facility uses encapsulation.

\subsection{\clasp{}}

The \clasp{} \commonlisp{} implementation%
\footnote{https://github.com/clasp-developers/clasp}
does not have the concept of breakpoints, nor does it have a stepper.
The \texttt{trace} facility uses encapsulation.

\subsection{\lispworks{}}

The \lispworks{} \commonlisp{} implementation%
\footnote{http://www.lispworks.com/products/lispworks.html}
provides breakpoints.  Breakpoints can be set either from the stepper
or from the editor.  The first time a breakpoint is set in a
definition, the source code of the defining form is re-evaluated with
additional annotations that provide information for the stepper.

When a breakpoint has been set, it is active no matter how the code
containing it was called.  If that code was called outside the
stepper, the stepper is automatically started.  Thus, breakpoints
provide the essential mechanism for the stepper.

Since setting a breakpoint requires access to the source code, and
since the source code of the system itself is not supplied, the user
can not set breakpoints in system code.

The \texttt{trace} facility in \lispworks{} is accomplished through
encapsulation.

\subsection{\allegro{}}

The \allegro{} \commonlisp{} implementation%
\footnote{https://franz.com/products/allegro-common-lisp/}
has the most complete and most sophisticated implementation of
breakpoints of all the \commonlisp{} implementations we investigated.

High-level debugging features are based on a low-level breakpoint
mechanism described in a paper by Duane
Rettig~\cite{Rettig:Instruction-level-breakpoints}.  In many respects,
the low-level mechanism is similar to the one used by \unix{}-style
debugging, in that it replaces the ordinary machine instruction by one
that will \emph{trap}, and thus cause the operating system to send a
signal to the Lisp process.  However, their mechanism differs in a
significant way from the one used by \unix{}-style debugging, in that
it allows the breakpoint to be handled by the same operating-system
process that contains it, with very few exceptions.

Same-process debugging is made possible by their mechanism that allows
existing breakpoints to be \emph{installed} or not.  Only installed
breakpoints correspond to replaced instructions, whereas uninstalled
breakpoints are remembered by the system and can be installed
according to the kind of debugging that the higher-level tool
implements.  The clever aspect of their mechanism is to have the
signal handler start its action by uninstalling all breakpoints.
Thus, even if a breakpoint exists in some system code that is also
used by the debugger, once the debugger is entered, the breakpoint is
no longer active.  Had the breakpoints remained installed, issuing
commands inside the debugger might have invoked some code with a
breakpoint, thereby halting the execution of the debugger itself.

This mechanism allows for instruction-level stepping in a way similar
to what is possible in separate-process \unix{}-style debuggers.  Just
as with \unix{}-style debugging, any instruction can be replaced by a
different one that will trap to the debugger.  As a result, it is
possible to execute one instruction at a time by simply trapping after
each instruction.  Crucially, however, this mechanism is then used to
build high-level tools such as source-level debuggers, steppers, etc.
